package com.joymedia.thor.page;

import lombok.Getter;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author XSH
 */
@Getter
public class PageImpl<T> implements Page<T> {
    private final int totalElements;
    private final int totalPages;
    private final int number;
    private final int page;
    private final List<T> content = new ArrayList<>();
    private final Pageable pageable;


    public PageImpl(List<T> content, Pageable pageable, int total) {
        if (content == null) {
            throw new IllegalArgumentException("Content must not be null!");
        }

        if (pageable == null) {
            throw new IllegalArgumentException("Pageable must not be null!");
        }

        this.totalElements = pageable.toOptional().filter(it -> !content.isEmpty())
                .filter(it -> it.getOffset() + it.getPageSize() > total)
                .map(it -> it.getOffset() + content.size())
                .orElse(total);

        this.content.addAll(content);
        this.pageable = pageable;
        this.totalPages = (totalElements - 1) / pageable.getPageSize() + 1;
        this.page = pageable.getPageNumber();
        this.number = pageable.getPageSize();
    }

    @Override
    public <R> PageImpl<R> convertTo(Function<T, R> mapper) {
        return new PageImpl<>(content.stream().map(mapper).collect(Collectors.toList()), pageable, totalElements);
    }

    @Override
    public List<T> getContent() {
        return content;
    }
}
